/**
 * Copyright (c) 2017-2024 Nop Platform. All rights reserved.
 * Author: canonical_entropy@163.com
 * Blog:   https://www.zhihu.com/people/canonical-entropy
 * Gitee:  https://gitee.com/canonical-entropy/nop-entropy
 * Github: https://github.com/entropy-cloud/nop-entropy
 */
package com.gitee.wsl.struct.table.impl

import com.gitee.wsl.struct.table.CellRange
import com.gitee.wsl.struct.table.ICellView
import com.gitee.wsl.struct.table.IColumnConfig
import com.gitee.wsl.struct.table.IRowView
import com.gitee.wsl.struct.table.ITableView
import kotlin.math.min


class SubTableView(val table: ITableView,
                   val range: CellRange) : ITableView by table {

    private var _rows: MutableList<IRowView?>? = null

    override var rows: List<IRowView?>
        set(value) {
            //_rows = value
        }
        get() {
            if (_rows == null) {
                _rows = ArrayList(rowCount)
                var i = 0
                val n = rowCount
                while (i < n) {
                    val baseRow = table.getRow(mapRow(i))
                    val row: SubRowView? = if (baseRow == null) null else SubRowView(this, baseRow, range)
                    _rows!!.add(row)
                    i++
                }
            }
            return _rows!!
        }

    override val rowCount: Int

    init {
        require(range.lastRowIndex < table.rowCount) { "invalid table range" }

        this.rowCount = min(table.rowCount - 1, range.lastRowIndex) - range.firstRowIndex + 1
    }

    override val colCount: Int
        get() = range.colCount

    fun mapRow(rowIndex: Int): Int {
        return range.firstColIndex + rowIndex
    }

    fun mapCol(colIndex: Int): Int {
        return range.firstColIndex+ colIndex
    }

    override fun getRow(rowIndex: Int): IRowView? {
        val cnt = this.rowCount
        if (rowIndex >= cnt) return null

        return rows[rowIndex]
    }

    override fun getCell(rowIndex: Int, colIndex: Int): ICellView? {
        return table.getCell(mapRow(rowIndex), mapCol(colIndex))
    }

    override fun getSubTable(range: CellRange): ITableView {
        return SubTableView(table, range.offset(range.firstRowIndex, range.firstColIndex))
    }

    override val cols: List<IColumnConfig>
        get() {
            val colTypes = table.cols

            val begin: Int = range.firstColIndex
            if (begin >= colTypes.size) return emptyList()

            var end: Int = range.lastColIndex + 1
            if (end > colTypes.size) end = colTypes.size
            return colTypes.subList(begin, end)
        }

    override fun getCol(colIndex: Int): IColumnConfig? {
        return table.getCol(colIndex + range.firstColIndex)
    }

    /*fun prop_get(propName: String?): Any {
        return table.prop_get(propName)
    }

    fun prop_has(propName: String?): Boolean {
        return table.prop_has(propName)
    }

    fun prop_set(propName: String?, value: Any?) {
        table.prop_set(propName, value)
    }*/
}